﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.Caching;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Reflection;

using MyLibrary.Data.SqlServer;
using MyLibrary.Data.Builder;
using MyLibrary.Data.Builder.Config;

namespace MyLibrary.Data.Builder.Component
{
    /// <summary>
    /// 建立数据报表的向导
    /// </summary>
    public class DataFormDirector
    {
        ReportLabelList _labels = null;
        HtmlTable _table = new HtmlTable();
        PlaceHolder _holder = null;
        /// <summary>
        /// 数据表单容器
        /// </summary>
        public PlaceHolder Holder
        {
            set { _holder = value; }
        }
        /// <summary>
        /// 空构造函数
        /// </summary>
        protected DataFormDirector()
        {

        }

        /// <summary>
        /// 建立数据报表的向导[构造函数]
        /// </summary>
        /// <param name="config">报表设置</param>
        public DataFormDirector(ReportConfig config)
        {
            _labels = config.ReportLabelList.Lables;
        }

        public void BuildDataForm()
        {
            DataFormBuilder builder = null;
            if (_labels.Count == 1)
                builder = new SingleLabelDataFromBuilder(_labels);
            else if (_labels.Count > 1)
                builder = new MultiLabelDataFromBuilder(_labels);
            DataFormLabel form = ConstructDataForm(builder);
            form.ShowDataForm(_holder, _table);
        }

        /// <summary>
        /// 建立数据表格
        /// </summary>
        /// <param name="builder">建立者</param>
        private DataFormLabel ConstructDataForm(DataFormBuilder builder)
        {
            if (builder is MultiLabelDataFromBuilder)
                builder.BuildDataFormLabel(ref _table);
            builder.BuildDataFormTitle(ref _table);
            builder.BuildDataFormContent(ref _table);
            return builder.GetDataFormLabel();
        }
    }

    /// <summary>
    /// 数据表建立者基类
    /// </summary>
    abstract class DataFormBuilder
    {
        public abstract string DBKey { get; set; }

        public abstract void BuildDataFormLabel(ref HtmlTable table);
        public abstract void BuildDataFormTitle(ref HtmlTable table);
        public abstract void BuildDataFormContent(ref HtmlTable table);
        public abstract DataFormLabel GetDataFormLabel();

        protected virtual void LoadColumnTitleFromTemplete(string filePath, ref HtmlTable table)
        {
            return;
        }

        /// <summary>
        /// 从数据库中获取源数据
        /// </summary>
        /// <param name="dbKey">数据库连接字符串</param>
        /// <param name="queryString">查询语句</param>
        /// <returns>查询结果</returns>
        protected virtual List<string> GetSourceFromDb(string dbKey, string queryString)
        {
            if (String.IsNullOrEmpty(queryString)) throw new ArgumentException("查询语句不能为空");
            string dbConnString = GetDbConnectionString(dbKey);
            if (String.IsNullOrEmpty(dbConnString)) throw new NullReferenceException("指定的数据库连接串键不存在");
            List<string> srcData = new List<string>();

            try
            {
                DataTable table = SQLServerHelper.ExecuteDataset(dbConnString, CommandType.Text, queryString).Tables[0];
                foreach (DataRow row in table.Rows)
                    srcData.Add(row[0].ToString());
                return srcData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private string GetDbConnectionString(string dbKey)
        {
            ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[dbKey];
            if (settings == null)
                return String.Empty;
            else
                return settings.ConnectionString;
        }
    }

    /// <summary>
    /// 展示标签
    /// </summary>
    class DataFormLabel
    {
        /// <summary>
        /// 展示数据表
        /// </summary>
        /// <param name="holder">容器</param>
        /// <param name="table">数据表</param>
        public void ShowDataForm(PlaceHolder holder, HtmlTable table)
        {
            holder.Controls.Clear();
            holder.Controls.Add(table);
        }
    }

    /// <summary>
    /// 单标签报表建立者
    /// </summary>
    class SingleLabelDataFromBuilder : DataFormBuilder
    {
        private ReportLabel _labelList = null;
        private string _dbKey = String.Empty;
        /// <summary>
        /// 数据库配置键
        /// </summary>
        public override string DBKey
        {
            get { return _dbKey; }
            set { _dbKey = value; }
        }

        /// <summary>
        /// 单标签报表建立者
        /// </summary>
        public SingleLabelDataFromBuilder(ReportLabelList list)
        {
            _labelList = list[0];
        }
        /// <summary>
        /// 单标签报表建立者
        /// </summary>
        protected SingleLabelDataFromBuilder()
        {
        }

        [ObsoleteAttribute("该方法在单标签报表中无法实现", true)]
        public override void BuildDataFormLabel(ref HtmlTable table)
        {
            throw new NotImplementedException("单标签报表的该方法没有实现");
        }

        /// <summary>
        /// 建立报表的标题
        /// </summary>
        public override void BuildDataFormTitle(ref HtmlTable table)
        {
            List<string> constColumn = new List<string>(); //固定列标题
            List<ReportColumn> dbColumns = new List<ReportColumn>();

            //标题列
            foreach (ReportColumn column in _labelList.ReportColumns.ColumnsList)
            {
                //查找是否存在模板
                if (column.ColumnType == "templete")
                {
                    if (String.IsNullOrEmpty(column.ColumnContent)) throw new ArgumentNullException("报表列头模板路径为空");
                    base.LoadColumnTitleFromTemplete(column.ColumnContent, ref table);
                    return;
                }
                else if (column.ColumnType == "const")
                    constColumn.Add(column.ColumnContent);
                else if (column.ColumnType == "database")
                    dbColumns.Add(column);
            }
            //开始构建报表的标题
            HtmlTableRow rowTitle = new HtmlTableRow();
            HtmlTableCell cell = null;
            //先添加固定列行
            foreach (string constTitle in constColumn)
            {
                cell = new HtmlTableCell("th");
                cell.InnerText = constTitle;
                rowTitle.Cells.Add(cell);
            }
            List<string> lstDbTitle = new List<string>();
            //添加来自与数据库的列头
            foreach (ReportColumn column in dbColumns)
            {
                lstDbTitle.Clear();
                lstDbTitle = base.GetSourceFromDb(this._dbKey, column.ColumnContent);
                foreach (string title in lstDbTitle)
                {
                    cell = new HtmlTableCell("th");
                    cell.InnerText = title;
                    rowTitle.Cells.Add(cell);
                }
            }
            table.Rows.Add(rowTitle);
        }

        /// <summary>
        /// 建立报表的内容
        /// </summary>
        public override void BuildDataFormContent(ref HtmlTable table)
        {
            if (String.IsNullOrEmpty(_labelList.ReportContent.AssemblyName) ||
               String.IsNullOrEmpty(_labelList.ReportContent.NameSpace))
                throw new NullReferenceException("配置文件中的,AssemblyName和NameSpace任一个不能为空");
            //建立Assembly的实体
            object instance = null;
            Type type = null;
            if (HttpContext.Current.Cache[_labelList.ReportContent.NameSpace] != null
                    && HttpContext.Current.Cache[_labelList.ReportContent.NameSpace + "_Type"] != null)
            {
                type = (Type)HttpContext.Current.Cache[_labelList.ReportContent.NameSpace + "_Type"];
                instance = HttpContext.Current.Cache[_labelList.ReportContent.NameSpace];
            }
            else
            {
                Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + @"\" + _labelList.ReportContent.AssemblyName);
                type = assembly.GetType(_labelList.ReportContent.NameSpace);
                instance = Activator.CreateInstance(type);
                HttpContext.Current.Cache.Add(_labelList.ReportContent.NameSpace, instance, null, DateTime.Now.AddMinutes(20), new TimeSpan(0, 20, 0), CacheItemPriority.Default, null);
                HttpContext.Current.Cache.Add(_labelList.ReportContent.NameSpace + "_Type", type, null, DateTime.Now.AddMinutes(20), new TimeSpan(0, 20, 0), CacheItemPriority.Default, null);
            }

            foreach (ReportDataSource ds in _labelList.ReportContent.DataSourceList)
            {
                //如果是Data字段
                if (ds.DatasourceType == "data")
                {
                    MethodInfo method = type.GetMethod(ds.DatasourceMethod);

                }
            }
        }

        public override DataFormLabel GetDataFormLabel()
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 多标签报表建立者
    /// </summary>
    class MultiLabelDataFromBuilder : DataFormBuilder
    {
        private ReportLabelList _labelList = null;

        public override string DBKey
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// 多标签报表建立者
        /// </summary>
        public MultiLabelDataFromBuilder(ReportLabelList list)
        {
            _labelList = list;
        }
        /// <summary>
        /// 多标签报表建立者
        /// </summary>
        protected MultiLabelDataFromBuilder()
        {
        }

        /// <summary>
        /// 建立报表的标签
        /// </summary>
        public override void BuildDataFormLabel(ref HtmlTable table)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 建立报表的标题
        /// </summary>
        public override void BuildDataFormTitle(ref HtmlTable table)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 建立报表的内容
        /// </summary>
        public override void BuildDataFormContent(ref HtmlTable table)
        {
            throw new NotImplementedException();
        }

        public override DataFormLabel GetDataFormLabel()
        {
            throw new NotImplementedException();
        }
    }
}
